package cz.muni.fi.pa165.languageschool.service.impl;

import cz.muni.fi.pa165.languageschool.Lecturer;
import cz.muni.fi.pa165.languageschool.Student;
import cz.muni.fi.pa165.languageschool.dao.LecturerDao;
import cz.muni.fi.pa165.languageschool.dao.StudentDao;
import cz.muni.fi.pa165.languageschool.utils.Authority;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * UserDetailsService implementation
 *
 * @author Milos, Marketa Trachtova (255498) marketa.tr(at)gmail.com
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    final static Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);

    @Autowired
    private StudentDao studentDao;
    @Autowired
    private LecturerDao lecturerDao;
    @Autowired
    private Assembler assembler;

    public UserDetailsServiceImpl() {
    }

    public UserDetailsServiceImpl(StudentDao studentDao, Assembler assembler) {
        this.studentDao = studentDao;
        this.assembler = assembler;
    }
    
    public LecturerDao getLecturerDao() {
        return lecturerDao;
    }

    public void setLecturerDao(LecturerDao lecturerDao) {
        this.lecturerDao = lecturerDao;
    }

    public void setStudentDao(StudentDao studentDao) {
        if (studentDao == null) {
            throw new NullPointerException("Argument studentDao was null");
        }
        this.studentDao = studentDao;
    }

    public StudentDao getStudentDao() {
        return this.studentDao;
    }

    public void setAssembler(Assembler assembler) {
        if (assembler == null) {
            throw new NullPointerException("Argument assembler was null");
        }
        this.assembler = assembler;
    }

    public Assembler getAssembler() {
        return this.assembler;
    }

    @Transactional(readOnly = true)
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
        log.info("*** SERVICE loadUserByUsername: {}", username);
        // UserDetails userDetails = null;
        Student student = null;
        Lecturer lecturer = null;
        //for the purpose of REST access this shall be the hardcoded user
        if (username.equalsIgnoreCase("rest")) {
            student = new Student();
            student.setUsername("rest");
            student.setPassword("rest");
            student.setAuthority(Authority.ROLE_ADMIN);
            student.setEnabled(true);
            return assembler.tranformStudentToUser(student);
        } 
         //for the purpose of WEB access this shall be the hardcoded user
        if (username.equalsIgnoreCase("admin")) {
            student = new Student();
            student.setUsername("admin");
            student.setPassword("admin");
            student.setAuthority(Authority.ROLE_ADMIN);
            student.setEnabled(true);
            return assembler.tranformStudentToUser(student);
        } 
        else {

            student = studentDao.findByUsername(username);

            if (student != null) {
                log.debug("user with username found: {}", student);
                return assembler.tranformStudentToUser(student);
            } else {
                lecturer = lecturerDao.findByUsername(username);
                log.debug("user with uresname found: {}", student);

                if (lecturer != null) {
                    return assembler.tranformLecturerToUser(lecturer);
                } else {
                    log.debug("user with uresname NOT found: {}", username);
                    throw new UsernameNotFoundException("user not found");

                }
            }
        }
    }
}
